// Generic helper function used by WindowSearch and other things.
// To help performance, it's the caller's responsibility to ensure that all params are not NULL.
{
if (!*aNeedle) // The empty string is always found, regardless of mode.
return true;
switch(g.TitleMatchMode)
{
case FIND_ANYWHERE: return strstr(aHaystack, aNeedle);
case FIND_REGEX: return RegExMatch(aHaystack, aNeedle);
case FIND_IN_LEADING_PART: return !strncmp(aHaystack, aNeedle, strlen(aNeedle));
default: // Otherwise: Exact match.
return !strcmp(aHaystack, aNeedle);
}
}
#define SEARCH_PHRASE_SIZE 1024
// Info from AutoIt3 source: GetWindowText fails under 95 if >65535, WM_GETTEXT randomly fails if > 32767.
// My: And since 32767 is what AutoIt3 passes to the API functions as the size (not the length, i.e.
// it can only store 32766 if room is left for the zero terminator) we'll use that for the size too.
// Note: MSDN says (for functions like GetWindowText): "Specifies the maximum number of characters to
// copy to the buffer, including the NULL character. If the text exceeds this limit, it is truncated."
#define WINDOW_TEXT_SIZE 32767
#define WINDOW_CLASS_SIZE 1024 // Haven't found anything that documents how long one can be, so use this.
// Bitwise fields to support multiple criteria in v1.0.36.02
#define CRITERION_TITLE 0x01
#define CRITERION_ID 0x02
#define CRITERION_PID 0x04
#define CRITERION_CLASS 0x08
#define CRITERION_GROUP 0x10
class WindowSearch
{
// One of the reasons for having this class is to avoid fetching PID, Class, and Window Text
// when only the criteria have changed but not the candidate window. This happens when called
// from the WinGroup class. Another reason is that it's probably more understandable than
// the old way, while eliminating some redundant code as well.
public:
DWORD mCriteria; // Which criteria are currently in effect (ID, PID, Class, Title, etc.)
// Controlled and initialized by SetCriteria():
global_struct *mSettings; // Settings such as TitleMatchMode and DetectHiddenWindows.
char mCriterionTitle[SEARCH_PHRASE_SIZE]; // For storing the title.
char mCriterionClass[SEARCH_PHRASE_SIZE]; // For storing the "ahk_class" class name.
size_t mCriterionTitleLength; // Length of mCriterionTitle.
char *mCriterionExcludeTitle; // ExcludeTitle.
size_t mCriterionExcludeTitleLength; // Length of the above.
char *mCriterionText; // WinText.
char *mCriterionExcludeText; // ExcludeText.
HWND mCriterionHwnd; // For "ahk_id".
DWORD mCriterionPID; // For "ahk_pid".
WinGroup *mCriterionGroup; // For "ahk_group".
bool mFindLastMatch; // Whether to keep searching even after a match is found, so that last one is found.
int mFoundCount; // Accumulates how many matches have been found (either 0 or 1 unless mFindLastMatch==true).
HWND mFoundParent; // Must be separate from mCandidateParent because some callers don't have access to IsMatch()'s return value.
HWND mFoundChild; // Needed by EnumChildFind() to store its result, and other things.
HWND *mAlreadyVisited; // Array of HWNDs to exclude from consideration.
int mAlreadyVisitedCount; // Count of items in the above.
WindowSpec *mFirstWinSpec; // Linked list used by the WinGroup commands.
ActionTypeType mActionType; // Used only by WinGroup::PerformShowWindow().
int mTimeToWaitForClose; // Same.
Var *mArrayStart; // Used by WinGetList() to fetch an array of matching HWNDs.
// Controlled by the SetCandidate() method:
HWND mCandidateParent;
DWORD mCandidatePID;
char mCandidateTitle[WINDOW_TEXT_SIZE]; // For storing title or class name of the given mCandidateParent.
char mCandidateClass[WINDOW_CLASS_SIZE]; // Must not share mem with mCandidateTitle because even if ahk_class is in effect, ExcludeTitle can also be in effect.
void SetCandidate(HWND aWnd) // Must be kept thread-safe since it may be called indirectly by the hook thread.
{
// For performance reasons, update the attributes only if the candidate window changed:
if (mCandidateParent != aWnd)
{
mCandidateParent = aWnd;
UpdateCandidateAttributes(); // In case mCandidateParent isn't NULL, update the PID/Class/etc. based on what was set above.